package com.may.websocket;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;

/**
 * @program: netty-websocket
 * @description:
 * @author: Bobby.Ma
 * @create: 2020-11-23 23:21
 **/
public class SocketChannelInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        ChannelPipeline pipeline = socketChannel.pipeline();
        //因为基于 http 协议，使用 http 的编/解码器
        pipeline.addLast(new HttpServerCodec());
        //是以块方式写，添加 ChunkedWriteHandler 处理器
        pipeline.addLast(new ChunkedWriteHandler());
        /*
            说明：
            1. http 数据在传输过程中是分段的，HttpObjectAggregator 可以将多个段聚合
            2. 这就是为什么，当浏览器发送大量数据时，就会发出多次 http 请求
        */
        pipeline.addLast(new HttpObjectAggregator(8192));//HttpObjectConstant.MAX_CONTENT_LENGTH
        /*
            说明：
            1. 对应 websocket ，它的数据是以帧(frame)的形式传递
            2. 可以看到 WebSocketFrame 下面有6个子类
            3. 浏览器请求时， ws://localhost:7000/may 表示请求 uri
            4. WebSocketServerProtocolHandler 核心功能将 http 协议升级为 ws 协议，保持长连接
            5. 通过一个状态码 101 切换协议
        */
        pipeline.addLast(new WebSocketServerProtocolHandler("/may"));
        // 自定义 handler 处理业务
        pipeline.addLast(new SocketHandler());
    }
}
